package com.lab303.powerproject.controller;


import com.lab303.powerproject.entity.*;
import com.lab303.powerproject.pojo.CustomAtlasDevice;
import com.lab303.powerproject.repository.DeviceTypeRepository;
import com.lab303.powerproject.service.DeviceService;
import com.lab303.powerproject.service.GraphInfoService;
import com.lab303.powerproject.service.RelationshipService;
import com.lab303.powerproject.util.FtpUtil;
import com.lab303.powerproject.util.ReadXml;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Controller
@RequestMapping("device")
public class DeviceController {

    public static final String UPLOAD_IMG = "image_upload";
    public static final String FTP_HOST = "49.234.228.157";
    public static final String PIC_HOST = "49.234.228.157";
    public static final int FTP_PORT = 21;
    public static final String FTP_USERNAME = "power";
    public static final String FTP_PASSWORD = "123456";

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private DeviceTypeRepository deviceTypeRepository;

    @Autowired
    private RelationshipService relationshipService;

    @Autowired
    private GraphInfoService graphInfoService;

    /**
     * 根据设备的id删除设备，返回设备列表页面
     * @param deviceId
     * @return
     */
    @GetMapping("/delete/{device_id}")
    private String deleteDevice(@PathVariable(value = "device_id") Integer deviceId){
        deviceService.deleteDeviceById(deviceId);
        return "device.html";
    }

    /**
     * 根据图谱id获取相应图谱的设备列表json格式
     * @param graphId
     * @return
     */
    @GetMapping("/getGraphDeviceList/{graphId}")
    @ResponseBody
    private Map getGraphDeviceList(@PathVariable(value = "graphId") Integer graphId){
        List devices = deviceService.getAtlasDevicesByGraphId(graphId);
        Map map = new HashMap();
        map.put("graphDeviceList",devices);
        return map;
    }

    /**
     * 获取所有设备列表，返回页面
     * @param model
     * @return
     */
    @GetMapping("/getAll")
    private String getAllDevice(Model model){
        List deviceList = deviceService.getAllDevices();
        model.addAttribute("deviceList",deviceList);
        return "device";
    }

    /**
     * 根据设备id获取设备，并跳转到设备修改页面
     * @param id
     * @param model
     * @return
     */
    @GetMapping("/get/{id}")
    private String getDevice(@PathVariable("id") Integer id,Model model){
        Device device = deviceService.findDeviceById(id);
        GraphInfo graphInfoById = graphInfoService.findGraphInfoById(device.getGraphId());
        String workTime = device.getWorkTime();
        String[] split = workTime.split("-");
        model.addAttribute("startTime",split[0]);
        model.addAttribute("endTime",split[1]);
        model.addAttribute("device",device);
        model.addAttribute("graphName",graphInfoById.getGraphName());
        return "deviceEdit";
    }

    /**
     * 根据关系边的源设备id获取包括该设备的所有边，返回json格式的数据
     * @param device_from
     * @return
     */
    @GetMapping("/getDeviceName/{device_from}")
    @ResponseBody
    private Map getDeviceName(@PathVariable(value = "device_from")Integer device_from){
        Map map = new HashMap();
        List relationship = relationshipService.findCustomRelationship(device_from);
        map.put("relationship",relationship);
        return map;
    }

    /**
     * 根据id获取设备的信息，并跳转到查看界面
     * @param id
     * @param model
     * @return
     */
    @GetMapping("/getDeviceInfo/{id}")
    private String getDeviceInfo(@PathVariable("id") Integer id,Model model){
        Device device = deviceService.findDeviceById(id);
        GraphInfo graphInfoById = graphInfoService.findGraphInfoById(device.getGraphId());
        String workTime = device.getWorkTime();
        String[] split = workTime.split("-");
        model.addAttribute("startTime",split[0]);
        model.addAttribute("endTime",split[1]);
        model.addAttribute("device",device);
        model.addAttribute("graphName",graphInfoById.getGraphName());
        return "deviceInfo";
    }

    /**
     * 跳转添加界面
     * @param typeId
     * @param model
     * @return
     */
    @GetMapping("/add/{type_id}")
    public String toAddPage(@PathVariable("type_id") Integer typeId,Model model){
        DeviceType deviceType = deviceTypeRepository.findById(typeId).orElse(null);
        List<GraphInfo> allGraphInfo = graphInfoService.getAllGraphInfo();
        model.addAttribute("deviceType",deviceType);
        model.addAttribute("graphList",allGraphInfo);
        return "deviceAdd";
    }

    /**
     * 设备添加处理，保存设备的图片信息和设备普通信息，然后将设备重定向到设备列表界面
     * @param type_id
     * @param request
     * @param device
     * @param pic
     * @return
     * @throws IOException
     */
    @PostMapping("/addDevice")
    public String addDevice(Integer type_id, HttpServletRequest request, Device device,@RequestParam("pic")MultipartFile[] pic) throws IOException {
        if (pic!=null||pic.length>0){
            FTPClient ftpClient = FtpUtil.getFTPClient(FTP_HOST, FTP_PORT, FTP_USERNAME, FTP_PASSWORD);
            String ftpPath = "/"+UPLOAD_IMG;
            for (int i = 0 ;i<pic.length;i++){
                if (!"".equals(pic[i].getOriginalFilename())) {
                    String fileName = UUID.randomUUID().toString() + pic[i].getOriginalFilename().substring(pic[i].getOriginalFilename().lastIndexOf("."));
                    FtpUtil.uploadFile(ftpClient, ftpPath, "", fileName, pic[i].getInputStream());
                    //pic[i].transferTo(new File("/home/power/image_upload/" + fileName));
                    if (i == 0) {
                        device.setPicPath("http://"+PIC_HOST+":10086/" + fileName);
                    } else {
                        device.setHighlightPicPath("http://"+PIC_HOST+":10086/" + fileName);
                    }
                }
            }
            ftpClient.logout();
        }
        DeviceType deviceType = deviceTypeRepository.findById(type_id).orElse(null);
        String[] propertyName = request.getParameterValues("propertyName");
        String[] propertyValue = request.getParameterValues("propertyValue");
        String[] times = request.getParameterValues("time");
        List<AdditionalProperties> propertyList = new ArrayList<>();
        if (propertyName!=null&&propertyValue!=null) {
            for (int i = 0; i < propertyName.length; i++) {
                AdditionalProperties property = new AdditionalProperties(propertyName[i], propertyValue[i]);
                property.setDevice(device);
                propertyList.add(property);
            }
        }
        device.setPropertyList(propertyList);
        device.setDeviceType(deviceType);
        device.setCreate_time(new Date());
        device.setWorkTime(times[0]+"-"+times[1]);
        Device savedDevice = deviceService.saveAndFlush(device);
        return "redirect:/device/"+device.getDeviceType().getTypeId();
    }

    /**
     * 修改设备的信息，页面的跳转交由前端去处理
     * @param device
     * @param pic
     * @param request
     * @return
     * @throws IOException
     */
    @PostMapping("/update")
    @ResponseBody
    private Map updateDevice(Device device,@RequestParam("pic") MultipartFile[] pic,HttpServletRequest request) throws IOException {
        Map map = new HashMap();
        String[] propertyId = request.getParameterValues("propertyId");
        String[] propertyName = request.getParameterValues("propertyName");
        String[] propertyValue = request.getParameterValues("propertyValue");
        String[] times = request.getParameterValues("time");
        Device deviceById = deviceService.findDeviceById(device.getDeviceId());
        deviceById.setDeviceName(device.getDeviceName()!=null?device.getDeviceName():deviceById.getDeviceName());
        deviceById.setCap(device.getCap());
        deviceById.setPower(device.getPower());
        deviceById.setxCoordinates(device.getxCoordinates());
        deviceById.setyCoordinates(device.getyCoordinates());
        deviceById.setIsPredicted(device.getIsPredicted());
        deviceById.setConversionRate(device.getConversionRate());
        deviceById.setWorkTime(times[0]+"-"+times[1]);
        Integer isInGraph = device.getIsInGraph();
        if (isInGraph==0){
            relationshipService.deleteRelationshipOfDevice(device.getDeviceId());
        }
        deviceById.setIsInGraph(device.getIsInGraph());
        deviceById.setDevCode(device.getDevCode()!=null?device.getDevCode():deviceById.getDevCode());
        deviceById.setBatteryCode(device.getBatteryCode()!=null?device.getBatteryCode():deviceById.getBatteryCode());
        deviceById.setTemperatureCode(device.getTemperatureCode()!=null?device.getTemperatureCode():deviceById.getTemperatureCode());
        List<AdditionalProperties> propertyList = new ArrayList<>(); 
        if(propertyId==null){
            if (propertyName!=null) {
                for (int i = 0; i < propertyName.length; i++) {
                    AdditionalProperties property = new AdditionalProperties(propertyName[i], propertyValue[i]);
                    property.setDevice(deviceById);
                    propertyList.add(property);
                }
            }
        }else {
            for (int i =0 ; i< propertyId.length;i++){
                AdditionalProperties property = new AdditionalProperties(propertyName[i],propertyValue[i]);
                property.setPropertyId(Integer.parseInt(propertyId[i]));
                property.setDevice(deviceById);
                propertyList.add(property);
            }
            for(int j  = propertyId.length;j<propertyName.length;j++){
                AdditionalProperties property = new AdditionalProperties(propertyName[j],propertyValue[j]);
                property.setDevice(deviceById);
                propertyList.add(property);
            }
        }
        deviceById.setPropertyList(propertyList);
        if (pic!=null&&pic.length!=0){
            FTPClient ftpClient = FtpUtil.getFTPClient(FTP_HOST, FTP_PORT, FTP_USERNAME, FTP_PASSWORD);
            String ftpPath = "/"+UPLOAD_IMG;
            for (int i = 0 ;i<pic.length;i++){
                if (!"".equals(pic[i].getOriginalFilename())) {
                    String fileName = UUID.randomUUID().toString() + pic[i].getOriginalFilename().substring(pic[i].getOriginalFilename().lastIndexOf("."));
                    FtpUtil.uploadFile(ftpClient, ftpPath, "", fileName, pic[i].getInputStream());
                    //pic[i].transferTo(new File("/home/power/image_upload/" + fileName));
                    if (i == 0) {
                        deviceById.setPicPath("http://"+PIC_HOST+":10086/" + fileName);
                    } else {
                        deviceById.setHighlightPicPath("http://"+PIC_HOST+":10086/" + fileName);
                    }
                }
            }
            ftpClient.logout();
        }
        deviceService.saveAndUpdateProperties(deviceById);
        map.put("message","update success");
        return map;
    }


    /**
     * 根据设备类型筛选设备，返回设备列表页面
     * @param typeId
     * @param model
     * @return
     */
    @GetMapping("/{type_id}")
    private String getAllDevicesByTypeId(@PathVariable("type_id") Integer typeId, Model model){
        List deviceList = deviceService.findDeviceByTypeId(typeId);
        model.addAttribute("deviceList",deviceList);
        return "device";
    }

    /**
     * 校验设备名字是否重复
     * @param deviceName
     * @return
     */
    @GetMapping("/check")
    @ResponseBody
    private Map checkDuplicateName(@RequestParam("deviceName")String deviceName){
        Map map = new HashMap();
        StringBuilder sb = new StringBuilder();
        boolean b = deviceService.checkDeviceName(deviceName);
        if (b) sb.append("yes");
        else sb.append("no");
        map.put("check",sb.toString());
        return map;
    }

    /**
     * 获取设备的高亮图片
     * @param deviceId
     * @return
     */
    @GetMapping("/getHighlightPic/{deviceId}")
    @ResponseBody
    public Map getHighlightPic(@PathVariable("deviceId")Integer deviceId){
        CustomAtlasDevice deviceById = deviceService.findCustomAtlasDeviceById(deviceId);
        Map map = new HashMap();
        map.put("highlight",deviceById.getHighlightPicPath());
        return map;
    }

    /**
     * 图谱拖拽界面，更新设备在图谱上的坐标
     * @param xmlString
     * @return
     */
    @GetMapping("/updateDeviceCoordinates")
    @ResponseBody
    public Map updateDeviceCoordinates(@RequestParam("xmlString")String xmlString){
        List<Device> list = ReadXml.readStringXml(xmlString);
        deviceService.updateDeviceCoordinates(list);
        Map map = new HashMap();
        map.put("message","success");
        return map;
    }

}
